/*
  书写 gulp 打包的配置文件
    + 按照 node 的 模块化 语法规则进行书写

  gulp 的下载
    + 如果你想使用 gulp 对你的项目进行打包
    1. 需要安装一个全局 gulp 工具
      => 打开命令行, 目录无所谓
      => 输入指令: $ npm install --global gulp
      => 作用: 在你的电脑内安装一个环境, 让你可以在命令行书写 gulp xxx 这样的指令
        -> 你的电脑有了可以打包项目的能力
      => 安装次数: 一台电脑安装一次, 以后直接使用
    2. 需要在项目内安装一个开发依赖 gulp 第三方模块
      => 打开命令行, 切换目录到你的项目根目录
      => 输入指令: $ npm install gulp --save-dev
      => 作用: 就是一个第三方模块, 让你在 gulpfile 文件内导入以后
        -> 得到一些可以操作文件的 API(方法) 供你使用
        -> 去完成 gulpfile 文件的配置
      => 安装次数: 每一个项目都需要安装一次
*/

/*
  1. 需要一个第三方模块来支持
    + 下载: npm i gulp
      => 下载以后, 会自动记录到 package.json 中 dependencies 字段内
      => 如果我下载一个 jquery, 也会记录到这个位置
      => 这时:
        -> 我们管 jquery 叫做项目依赖, 项目的运行需要依赖这个第三方
        -> 我们管 gulp 叫做开发依赖, 指只在开发阶段使用的第三方
        -> 但是两种第三方依赖是记录在一起的, 不好
      => 推荐:
        -> 安装开发依赖的时候
        -> 使用指令: $ npm install --save-dev 包名
                    $ npm i -D 包名
        -> 下载下来的内容和 'npm i 包名' 下载下来的内容一模一样
        -> 只是在 package.json 文件内记录的位置不一样
    + 导入: const gulp = require('gulp')
      => 因为是第三方模块
      => 会自动去到 node_modules 内查找
      => 直接按照 包名 来导入就可以了
    + 常用方法
      => 当 gulp 被导入了以后, 会给我们提供一些方法
      1-1. gulp.tesk('名称', 函数)
        -> 作用: 创建一个任务, 函数内书写该任务需要执行的代码
      1-2. gulp.src('路径')
        -> 作用: 找到源文件
        -> 路径:
          + index.css    指定查找某一个文件
          + *.css        所有 .css 结尾的文件
          + ** /*        所有文件夹下的所有文件
          + ...
      1-3. gulp.pipe(工作内容)
        -> 作用: 用来执行各项工作内容的
      1-4. gulp.dest('路径')
        -> 作用: 把文件放入哪一个文件夹
      1-5. gulp.series(任务1, 任务2, 任务3, ...)
        -> 作用: 逐个执行每一个任务
        -> 前一个任务做完, 在做下一个任务
      1-6. gulp.parallel(任务1, 任务2, 任务3, ...)
        -> 作用: 并行开始每一个任务
        -> 所有任务同时开始
      1-7. gulp.watch('文件', 任务)
        -> 作用: 监控指定文件
        -> 当文件发生任何改变的时候, 直接执行任务
*/

/*
  2. 配置一个打包 css 的任务
    + 利用 gulp.tesk() 方法来创建一个打包任务
      => 在里面使用 gulp.src 进行查找源文件
      => 使用 pipe 来进行流运转
      => 使用 gulp.dest() 方法把打包好的内容放在指定文件夹内
      => 这个语法不推荐, 因为是属于 gulp@3.x 的语法
    + gulp@4.x 的时候, 我们推荐的语法
      => const 任务名 = 函数
      => 函数内的内容不变, 定义任务的方式改变一下
      => 需要使用导出语法把该 任务 导出
        -> module.exports = { 任务名 }
    + 执行任务
      => 打开命令行, 目录切换到项目根目录
      => 输入指令: $ gulp 任务名称
        -> 就会执行 gulpfile.js 文件导出的那个任务
        -> 如果没有导出, 就会报错
    + 如果对 css 代码进行压缩
      => 需要利用到一个叫做 gulp-cssmin 的第三方
      => 下载: $ npm i -D gulp-cssmin
      => 导入: const cssmin = require('gulp-cssmin')
        -> 导入以后, 你会得到一个函数, 直接执行就能压缩 css

  扩展:
    + 打包 css 的时候自动添加前缀
    + 思考: 什么时候加 ?
      => 就是在找到源文件 和 压缩之间
      => 添加一个步骤, 自动添加前缀
    + 使用一个第三方模块来完成叫做 gulp-autoprefixer
      => 下载: $ npm i -D gulp-autoprefixer
      => 导入: const autoprefixer = require('gulp-autoprefixer')
        -> 导入以后, 你会得到一个函数, 直接执行就能自动添加前缀
        -> 需要传递参数: 表示你要兼容到哪些浏览器
    + 执行的时候会有警告提示, 解决问题
      => 原因: 不推荐在使用插件的时候传递参数
        -> 推荐放在配置文件内
      => 解决: 把配置项以 browserslist 字段写在 package.json 内
*/

/*
  3. 配置一个打包 sass 的任务
    + 准备一个 sass 的任务函数
    + 导出
    + 在函数内进行打包 sass 任务的配置
      => 找到 sass 文件
      => 把 sass 语法转换成 css 语法
      => 自动添加前缀
      => 压缩 css 文件
      => 放在一个指定的目录内
    + 如何把 sass 转换成 css
      => 需要使用一个 第三方包, 叫做 gulp-sass
      => 下载: $ npm install --save-dev gulp-sass
            npm i -D gulp-sass
        -> 原因:
          + 因为 gulp-sass 这个第三方依赖了一个 node-sass 的第三方
          + 在你下载 gulp-sass 的时候, 会自动下载 node-sass 这个第三方
          + node-sass 这个第三方在 npm 上是一个 压缩包(zip), 下载以后需要解压
          + 就会导致下载 node-sass 失败
        -> 解决:
          + 下载 node-sass 使用单独的下载地址
          + 有人做了把 node-sass 转换成和其他的包一样的状态
          + 在下载 gulp-sass 之前, 我们临时设置一个下载地址
          + 打开命令行, 输入指令: $ set SASS_BINARY_PATH=D:\win32-x64-57_binding.node
          + 然后再次尝试下载
      => 导入: const sass = require('gulp-sass')
        -> 导入以后, 得到一个函数, 直接调用就能把 sass 转换成 css 文件

    最新版 打包 gulp-sass
    下载：npm i -D gulp-sass
         npm i -D node-sass
         npm i -D sass
    下载失败：
    切换下载地址：
    set SASS_BINARY_PATH=D:\win32-x64-57_binding.node
    再次下载
    只需要导入一个 gulp-sass
    语法： const sass = require('gulp-sass')(require('sass'))

*/

/*
  4. 配置一个打包 js 的任务
    + 创建任务函数
    + 导出
    + 在函数内配置打包 js 的过程
      => 获取到你要打包的 js 文件
      => 进行压缩
      => 放到指定的路径内
    + 如何压缩 js 代码
      => 需要用到一个第三方模块, 叫做 gulp-uglify
      => 下载: $ npm i -D gulp-uglify
      => 导入: const uglify = require('gulp-uglify')
        -> 导入以后得到一个函数, 直接执行就能对 js 代码进行压缩
      => 注意: js 内书写 ES6 及以上的语法
        -> 不会进行转码, 原样打包
    + 如何进行 ES6 语法转换
      => 什么时候转 ?
        -> 找到文件, 压缩之前转码
      => 使用一个第三方包, 叫做 gulp-babel
        -> 下载: npm i -D gulp-babel @babel/core @babel/preset-env
          + 因为 gulp-babel 的运行需要依赖一个叫做 @babel/core 的包
          + 因为 gulp-babel 的运行需要依赖一个叫做 @babel/preset-env 的包
          + 但是他自己不会下载, 需要手动下载一下
        -> 导入: const babel = require('gulp-babel')
          -> 导入以后得到一个函数, 直接执行就好
          -> 使用的时候需要传递一个参数
          -> {presets: [ '@babel/preset-env' ]}
    + 总结一下 js 的打包工作
      => 如果你只是想打包, 不需要 ES6 转码
        -> 下载 gulp-uglify, 直接导入使用
      => 如果你想 ES6 转码
        -> 下载三个包
          + gulp-babel
          + @babel/core
          + @babel/preset-env
        -> 导入只需要导入 gulp-babel
        -> 使用的时候 babel({ presets: [ '@babel/preset-env' ] })
*/

/*
  5. 配置一个打包 html 文件的任务
    + 准备一个任务函数
    + 导出
    + 在函数内书写打包 html 的流程
      => 找到指定的 html 文件
      => 进行压缩打包
      => 放在指定的目录内
    + 如何压缩 html 文件
      => 需要一个第三方包叫做 gulp-htmlmin
      => 下载: $ npm i -D gulp-htmlmin
      => 导入: const htmlmin = require('gulp-htmlmin')
        -> 导入以后得到一个函数, 直接调用就可以了
        -> 但是不会对 html 文件进行任何修改
        -> 向压缩 html 文件, 需要配置参数
*/

/*
  6. 配置处理 图片 视音频等静态文件的任务
    + 创建一个处理相应内容的函数
    + 导出函数
    + 在函数内配置打包流程
      => 找到原始文件
      => 压缩
      => 放到指定目录
    + 以图片为例:
      => 压缩图片使用 gulp-imagemin 第三方
      => 导入以后, 直接调用
    + 静态资源都是经过处理以后给我们的
      => 我们不需要任何操作
      => 只要转换位置就可以了
*/

/*
  11. 配置一个总任务
    + 准备任务函数(建议导出的时候起名叫做 default)
      => 当你在命令行输入 gulp default 的时候
      => 有一个简写形式, 叫做 $ gulp
      => 默认就是执行一个叫做 default 的任务
    + 导出这个函数
    + 书写任务内容
      => 同时把其他所有的打包任务都执行了
    + 需要做的事情:
      => 可以并行执行所有任务
      => 使用 gulp.parallel()
      => 返回值: 一个函数, 等待执行
*/

/*
  12. 配置一个 删除 任务
    + 目前的打包配置
      => 当你源文件内文件名修改的时候
      => 会导致 dist 内有多余文件出现
    + 解决:
      => 在每一次打包之前, 把 dist 文件夹删除掉
      => 每一次都打包当前的内容
    + 使用一个叫做 del 的第三方包, 删除 dist 文件夹
      => 下载: npm i -D del
      => 导入: const del = require('del')
        -> 语法: del([ '要删除的文件夹目录' ])
    + 最好把这个删除任务也配置在总任务内
      => 和其他的打包任务有没有顺序关系
      => 执行完毕删除任务, 在执行其他的打包任务
      => gulp.series()
*/

/*
  13. 配置一个启动服务器的任务
    + 这个任务是在开发过程中来使用
      => 提供热刷新, 提供代理配置
    + 需要一个叫做 gulp-webserver 的第三方包
      => 下载: $ npm i -D gulp-webserver
      => 导入: const webserver = require('gulp-webserver')
        -> 导入以后, 得到一个函数, 直接调用
        -> 配置一些参数实现启动服务器
    + 域名配置:
      => 默认是写 localhost
      => 你可以自定义域名
        -> 需要你修改一次配置文件
        -> win: C:/windows/system32/drives/etc/hosts 文件
        -> mac: command + shift + g, 输入 /etc 回车, 找到 hosts 文件
        -> 添加一行代码  127.0.0.1      你的自定义域名
    + 如何配置代理
      => 在 webserver 的配置项中加一个选项
      => proxies: [
        {
          source: 代理标识符,
          target: 代理目标地址
        },
        {},
        {},
        {}
      ]
*/

/*
  14. 配置一个监控任务
    + 作用: 当 src 内任何文件发生变化的时候, 从新进行打包操作
      => 就会导致 dist 内的文件发生变化
      => dist 内的文件发生变化, 就会从新刷新页面显示内容
    + 使用的是 gulp.watch('监控的文件', 执行的任务)
*/

// 1. 导入 gulp 第三方模块
const gulp = require('gulp')
// 1-2. 导入 gulp-cssmin 第三方模块, 用于压缩 css 文件
const cssmin = require('gulp-cssmin')
// 1-2-2. 导入 gulp-autoprefixer 第三方, 用于自动添加前缀
const autoprefixer = require('gulp-autoprefixer')
// 1-3. 导入 gulp-sass 第三方, 用于把 sass 代码转换成 css 代码
// const sass = require('gulp-sass')
// 1-4. 导入 gulp-uglify 第三方, 用于把 js 代码压缩
const uglify = require('gulp-uglify')
// 1-4-2. 导入 gulp-babel 第三方, 用于把 es6 转换成 es5
const babel = require('gulp-babel')
// 1-5. 导入 gulp-htmlmin 第三方, 用于压缩 html 文件
const htmlmin = require('gulp-htmlmin')
// 1-12. 导入 del 第三方, 用于删除文件夹
// const del = require('del')
// 1-13. 导入 gulp-webserver 第三方, 用于在开发阶段启动服务器
// const webserver = require('gulp-webserver')

// 2. 配置一个 打包 css 的任务
const cssHandler = () => {
  // 在配置任务的时候, 把 流 return 出去
  return gulp
    .src('./src/css/*.css')               // 找到原始文件
    .pipe(autoprefixer())                 // 自动添加前缀
    .pipe(cssmin())                       // 进行 css 代码的压缩
    .pipe(gulp.dest('./dist/css/'))       // 放在指定目录内
}

// 3. 配置一个 打包 sass 文件的任务
// const sassHandler = () => {
//   return gulp
//     .src('./src/sass/*.scss')         // 找到需要编译的 sass 文件
//     .pipe(sass())                     // 进行 sass 转换成 css 的操作
//     .pipe(autoprefixer())             // 给 css 代码自动添加前缀
//     .pipe(cssmin())                   // 对 css 代码进行压缩处理
//     .pipe(gulp.dest('./dist/sass/'))  // 放在指定目录下
// }

// 4. 配置一个打包 js 文件的任务
const jsHandler = () => {
  return gulp
    .src('./src/js/*.js')
    .pipe(babel({ presets: [ '@babel/preset-env' ] })) // 把 ES6 转换成 ES5
    .pipe(uglify()) // 压缩 js 文件
    .pipe(gulp.dest('./dist/js/'))
}

// 5. 配置一个打包 html 文件的任务
const htmlHandler = () => {
  return gulp
    .src('./src/views/*.html')
    .pipe(htmlmin({ // 进行压缩
      collapseWhitespace: true, // 把所有空格去掉
      collapseBooleanAttributes: true, // 简写所有布尔属性
      removeAttributeQuotes: true, // 移除属性中的双引号
      removeEmptyAttributes: true, // 移除空属性
      removeComments: true, // 移除注释内容
      removeScriptTypeAttributes: true, // 移除 script 标签默认的 type 属性
      removeStyleLinkTypeAttributes: true, // 移除 link 和 style 标签的默认 type 属性
      minifyCSS: true, // 压缩内嵌式 css 代码
      minifyJS: true, // 压缩内嵌式 js 代码
    }))
    .pipe(gulp.dest('./dist/views/'))
}

// 6. 配置一个转移 img 文件的任务
const imgHandler = () => {
  return gulp
    .src('./src/images/**.*')
    .pipe(gulp.dest('./dist/images/'))
}

// 7. 配置一个转移 video 文件的任务
// const videoHandler = () => {
//   return gulp
//     .src('./src/videos/**.*')
//     .pipe(gulp.dest('./dist/videos/'))
// }

// 8. 配置一个转移 audio 文件的任务
// const audioHandler = () => {
//   return gulp
//     .src('./src/audios/**.*')
//     .pipe(gulp.dest('./dist/audios/'))
// }

// 9. 配置一个转移 fonts 文件的任务
// const fontHandler = () => {
//   return gulp
//     .src('./src/fonts/**.*')
//     .pipe(gulp.dest('./dist/fonts/'))
// }

// 10. 配置一个转移 data 文件的任务
// const dataHandler = () => {
//   return gulp
//     .src('./src/data/**.*')
//     .pipe(gulp.dest('./dist/data/'))
// }

// 12. 配置一个删除任务
// const delHandler = () => {
//   return del(['./dist/'])
// }

// 13. 配置一个启动服务器的任务
// const serverHandler = () => {
//   return gulp
//     .src('./dist') // 找到你要开启的文件夹, 打包后生成的文件夹
//     .pipe(webserver({ // 配置启动服务器
//       host: 'www.guoxiang.com', // 域名
//       port: '8080', // 端口号
//       open: './views/index.html', // 默认打开哪一个 html 文件, 你网站默认的首页
//       livereload: true, // 自动刷新页面, 当你的代码发生任何修改以后, 会自动刷新页面
//       // 开始进行代理配置
//       proxies: [
//         {
//           // 代理标识符
//           source: '/dt',
//           // 跨域的请求地址
//           target: 'https://www.duitang.com/napi/blog/list/by_filter_id/'
//         }
//       ]
//     }))
// }

// 14. 配置一个监控任务
const watchHandler = () => {
  gulp.watch('./src/css/*.css', cssHandler)
  gulp.watch('./src/js/*.js', jsHandler)
  // gulp.watch('./src/sass/*.sass', sassHandler)
  gulp.watch('./src/views/*.html', htmlHandler)
}

// 11. 配置一个总任务
const defaultHandler = gulp.series(
  // delHandler,
  gulp.parallel(cssHandler, jsHandler, htmlHandler, imgHandler),
)

// end 导出你配置的任务
module.exports = {
  cssHandler,
  // sassHandler,
  jsHandler,
  htmlHandler,
  imgHandler,
  // videoHandler,
  // audioHandler,
  // fontHandler,
  // dataHandler,
  default: defaultHandler,
  // delHandler
}



















// // 假如我想做一个 打包 css 文件的配置
// // gulp@3.x 的语法
// gulp.tesk('cssHandler', function () {
//   // 在这里面书写打包 css 文件的工作流程
//   gulp
//     .src('./src/css/*.css')
//     .pipe('把css文件进行压缩转码')
//     .pipe(gulp.dest('./dist/css/'))
// })
